package gameAppLayer;

import galaxies.CustomGalaxyData;
import galaxies.enums.EGalaxyAge;
import galaxies.enums.EGalaxyType;
import galaxies.enums.EQuickZones;
import galaxies.enums.ERandomDial;
import galaxies.enums.ESlowZones;
import galaxies.enums.EarthLike;
import galaxies.enums.GalaxyDensity;
import galaxies.enums.GalaxySize;
import galaxies.enums.ResearchRate;
import gameAppLayer.enums.Constants;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;

import com.thoughtworks.xstream.XStream;

import population.Clade;
import population.EDifficulty;
import population.EEffectsDetails;
import population.EReligionStrength;
import population.ETransitSpeed;
import population.Flag;
import population.Government;
import population.Religion;
import population.StateReligion;


/*
 * Container that holds all game setting information from main menus
 */
public class GameSettings {	
	
	XStream xstream = new XStream();
	
	/*
	 * Universe settings
	 */
	private HashMap<String, Integer> galSizes = new HashMap<String, Integer>();
	//private HashMap<String, Integer> numStars = new HashMap<String, Integer>(); //
	private HashMap<String, EGalaxyType> galaxyType = new HashMap<String, EGalaxyType>();
	private HashMap<String, EGalaxyAge> galaxyAge = new HashMap<String, EGalaxyAge>();
	private HashMap<String, Double> earthlike = new HashMap<String, Double>();
	private HashMap<String, Integer> galaxyDensity = new HashMap<String, Integer>();
	private HashMap<String, Integer> numArms = new HashMap<String, Integer>();
	
	private ArrayList<String> galaxies = new ArrayList<String>();
	private HashMap<String, CustomGalaxyData> customData = new HashMap<String, CustomGalaxyData>(); //for custom galaxy maps
	
	private int numGalaxies;
	private EQuickZones quickZone;
	private ESlowZones slowZone;
	private ERandomDial randomDial;
	private boolean megaEventsEnabled; //toggle random megaEvents
	//private EResearchRate researchRate;
	private Double researchRate;
	
	private int totalStars; //computed automatically by adding up numStars
	
	/*
	 * Starting nation setup information
	 */
	private Clade nationClade;
	private Religion nationReligion;
	private EReligionStrength nationReligionStrength;
	private String nationName;
	private Flag nationFlag;
	
	/*
	 * Starting state setup information
	 */
	private Clade coreClade; //the core, starting Clade of the state
	private ArrayList<Clade> clades = new ArrayList<Clade>();
	private ArrayList<Religion> religions = new ArrayList<Religion>();
	private StateReligion stateReligion;
	private Government government;
	private String stateName;
	private Flag stateFlag; //state flag (nations have their own flags, separate)
	private EDifficulty difficulty;
	
	/*
	 * Starting state setup information - additional options
	 */
	private boolean spyMissionsEnabled; //toggles spy missions on/off
	private boolean monoStatesEnabled; //single nation states only
	private boolean noUnificationEnabled; //eliminates unification treaties
	private ETransitSpeed transitSpeed; //toggles between All, STL-only, FTL-only, Wormhole-only
	private boolean quietStartEnabled; //reduced number of arkships at start
	private int numArkShips; //chosen along with quietStart
	private boolean autoResolveCombatsEnabled;
	private boolean highlightEnemyMovesEnabled;
	private boolean highlightFriendlyMovesEnabled;	
	
	
	/*
	 * Options - Graphics settings
	 */
	//Resolution settings(??)
	private EEffectsDetails mainEffects; //detail level for textures, etc. in strategy mode
	private EEffectsDetails combatEffects; //detail level for combat textures, etc.
	private boolean backgroundStarsEnabled; //toggles background stars/galaxy clumps
		
	/*
	 * Options - Audio settings
	 */
	private int fxVolume; //1 to 100
	private int musicVolume; //1 to 100
	private int interfaceVolume; //1 to 100
	private int masterVolume; //1 to 100
	//Audio quality settings(??)
	
	/*
	 * Options - Input settings
	 */
	private int mouseSensitivity; //1 to 100
	//Keybindings list(??)
	
	
	/*
	 * Options - Input - Combat settings
	 */
	//Keybindings list(??)
	
	/*
	 * Options - Miscellaneous
	 */
	private boolean showClockEnabled;
	private boolean milClockEnabled; //clock displays 24hr time
	private boolean alarmOn;
	private int alarmHour;
	private int alarmMinute;
	private boolean alarmAM; //time is AM if true	
	
	
	
	public GameSettings(){};	
	
	public void addGalaxy(String galRef, int galSize, EGalaxyType type, int density,
			EGalaxyAge age, double earthlike) {
		
		this.galaxies.add(galRef);
		this.numGalaxies++;
		this.galSizes.put(galRef, galSize);
		//this.numStars.put(galRef, numStars);
		this.galaxyType.put(galRef, type);
		this.galaxyAge.put(galRef, age);
		this.galaxyDensity.put(galRef, density);
		this.earthlike.put(galRef, earthlike);
		
	}
	
	//For custom galaxies
	public void addGalaxy(String galRef, int galSize, EGalaxyType type, int density,
			EGalaxyAge age, double earthlike, CustomGalaxyData galData) {
		
		this.galaxies.add(galRef);
		this.numGalaxies++;
		this.galSizes.put(galRef, galSize);
		//this.numStars.put(galRef, numStars);
		this.galaxyType.put(galRef, type);
		this.galaxyAge.put(galRef, age);
		this.galaxyDensity.put(galRef, density);
		this.earthlike.put(galRef, earthlike);
		this.customData.put(galRef, galData);		
	}
	
	public void removeGalaxy(String galRef) {
		this.galaxies.remove(galRef);
		this.numGalaxies--;
		this.galSizes.remove(galRef);
		//this.totalStars -= numStars.get(galRef);
		//this.numStars.remove(galRef);
		this.galaxyType.remove(galRef);
		this.galaxyAge.remove(galRef);
		this.galaxyDensity.remove(galRef);
		this.earthlike.remove(galRef);		
		this.customData.remove(galRef);
	}
	
	
	
	
	public HashMap<String, Integer> getGalSizes() {
		return this.galSizes;
	}
	
	public Integer getGalSizes(String galRef) {
		return this.galSizes.get(galRef);
	}
	
//	public HashMap<String, Integer> getNumStars() {
//		return this.numStars;
//	}
//	
//	public Integer getNumStars(String galRef) {
//		return this.numStars.get(galRef);
//	}
	
	public HashMap<String, EGalaxyType> getGalaxyType() {
		return this.galaxyType;		
	}
	
	public EGalaxyType getGalaxyType(String galRef) {
		return this.galaxyType.get(galRef);
	}
	
	public HashMap<String, EGalaxyAge> getGalaxyAge() {
		return this.galaxyAge;
	}
	
	public EGalaxyAge getGalaxyAge(String galRef) {
		return this.galaxyAge.get(galRef);
	}
	
	public HashMap<String, Double> getEarthlike() {
		return this.earthlike;
	}
	
	public Double getEarthlike(String galRef) {
		return this.earthlike.get(galRef);
	}
	
	public HashMap<String, Integer> getGalaxyDensity() {
		return this.galaxyDensity;
	}
	
	public Integer getGalaxyDensity(String galRef) {
		return this.galaxyDensity.get(galRef);
	}
	
	public ArrayList<String> getGalaxyRefs() {
		return this.galaxies;
	}
	
	
	
	
	
	
	
	
	
	public EQuickZones getQuickZone() {
		return quickZone;
	}

	public void setQuickZone(EQuickZones quickZone) {
		this.quickZone = quickZone;
	}

	public ESlowZones getSlowZone() {
		return slowZone;
	}

	public void setSlowZone(ESlowZones slowZone) {
		this.slowZone = slowZone;
	}

	public ERandomDial getRandomDial() {
		return randomDial;
	}

	public void setRandomDial(ERandomDial randomDial) {
		this.randomDial = randomDial;
	}

	private void setTotalStars(int totalStars) {
		this.totalStars = totalStars;
	}

	public int getTotalStars() {
		return totalStars;
	}

	public boolean isMegaEvents() {
		return megaEventsEnabled;
	}

	public void setMegaEvents(boolean megaEvents) {
		this.megaEventsEnabled = megaEvents;
	}

	public double getResearchRate() {
		return researchRate;
	}


	public void setResearchRate(Double researchRate) {
		this.researchRate = researchRate;
	}


	public Clade getNationClade() {
		return nationClade;
	}


	public void setNationClade(Clade clade) {
		this.nationClade = clade;
	}


	public Religion getNationReligion() {
		return nationReligion;
	}


	public void setNationReligion(Religion religion) {
		this.nationReligion = religion;
	}


	public String getNationName() {
		return nationName;
	}

	public void setNationName(String nationName) {
		this.nationName = nationName;
	}

	public String getStateName() {
		return stateName;
	}

	public void setStateName(String stateName) {
		this.stateName = stateName;
	}

	public Flag getStateFlag() {
		return stateFlag;
	}

	public void setStateFlag(Flag stateFlag) {
		this.stateFlag = stateFlag;
	}

	public Government getGovernment() {
		return government;
	}

	public void setGovernment(Government government) {
		this.government = government;
	}

	public EDifficulty getDifficulty() {
		return difficulty;
	}



	public void setDifficulty(EDifficulty difficulty) {
		this.difficulty = difficulty;
	}

	public boolean isSpyMissions() {
		return spyMissionsEnabled;
	}

	public void setSpyMissions(boolean spyMissions) {
		this.spyMissionsEnabled = spyMissions;
	}

	public boolean isMonoStates() {
		return monoStatesEnabled;
	}

	public void setMonoStates(boolean monoStates) {
		this.monoStatesEnabled = monoStates;
	}

	public boolean isNoUnification() {
		return noUnificationEnabled;
	}

	public void setNoUnification(boolean noUnification) {
		this.noUnificationEnabled = noUnification;
	}

	public ETransitSpeed getTransitSpeed() {
		return transitSpeed;
	}

	public void setTransitSpeed(ETransitSpeed transitSpeed) {
		this.transitSpeed = transitSpeed;
	}

	public boolean isQuietStart() {
		return quietStartEnabled;
	}

	public void setQuietStart(boolean quietStart) {
		this.quietStartEnabled = quietStart;
	}

	public int getNumArkShips() {
		return numArkShips;
	}

	public void setNumArkShips(int numArkShips) {
		this.numArkShips = numArkShips;
	}

	public boolean isAutoResolveCombats() {
		return autoResolveCombatsEnabled;
	}

	public void setAutoResolveCombats(boolean autoResolveCombats) {
		this.autoResolveCombatsEnabled = autoResolveCombats;
	}

	public boolean isHighlightEnemyMoves() {
		return highlightEnemyMovesEnabled;
	}

	public void setHighlightEnemyMoves(boolean highlightEnemyMoves) {
		this.highlightEnemyMovesEnabled = highlightEnemyMoves;
	}

	public boolean isHighlightFriendlyMoves() {
		return highlightFriendlyMovesEnabled;
	}

	public void setHighlightFriendlyMoves(boolean highlightFriendlyMoves) {
		this.highlightFriendlyMovesEnabled = highlightFriendlyMoves;
	}

	public EEffectsDetails getMainEffects() {
		return mainEffects;
	}

	public void setMainEffects(EEffectsDetails mainEffects) {
		this.mainEffects = mainEffects;
	}

	public EEffectsDetails getCombatEffects() {
		return combatEffects;
	}

	public void setCombatEffects(EEffectsDetails combatEffects) {
		this.combatEffects = combatEffects;
	}

	public boolean isBackgroundStars() {
		return backgroundStarsEnabled;
	}

	public void setBackgroundStars(boolean backgroundStars) {
		this.backgroundStarsEnabled = backgroundStars;
	}

	public int getFxVolume() {
		return fxVolume;
	}

	public void setFxVolume(int fxVolume) {
		if (fxVolume > 100) {
			fxVolume = 100;
		}
		else if (fxVolume < 0) {
			fxVolume = 0;
		}
		this.fxVolume = fxVolume;
	}

	public int getMusicVolume() {
		return musicVolume;
	}

	public void setMusicVolume(int musicVolume) {
		if (musicVolume > 100) {
			musicVolume = 100;
		}
		else if (musicVolume < 0) {
			musicVolume = 0;
		}
		this.musicVolume = musicVolume;
	}

	public int getInterfaceVolume() {
		return interfaceVolume;
	}

	public void setInterfaceVolume(int interfaceVolume) {
		if (interfaceVolume > 100) {
			interfaceVolume = 100;
		}
		else if (interfaceVolume < 0) {
			interfaceVolume = 0;
		}
		this.interfaceVolume = interfaceVolume;
	}

	public int getMasterVolume() {
		return masterVolume;
	}

	public void setMasterVolume(int masterVolume) {
		if (masterVolume > 100) {
			masterVolume = 100;
		}
		else if (masterVolume < 0) {
			masterVolume = 0;
		}
		this.masterVolume = masterVolume;
	}

	public int getMouseSensitivity() {
		return mouseSensitivity;
	}

	public void setMouseSensitivity(int mouseSensitivity) {
		if (mouseSensitivity > 100) {
			mouseSensitivity = 100;
		}
		else if (mouseSensitivity < 0) {
			mouseSensitivity = 0;
		}
		this.mouseSensitivity = mouseSensitivity;
	}

	public boolean isShowClock() {
		return showClockEnabled;
	}

	public void setShowClock(boolean showClock) {
		this.showClockEnabled = showClock;
	}

	public boolean isMilClock() {
		return milClockEnabled;
	}

	public void setMilClock(boolean milClock) {
		this.milClockEnabled = milClock;
	}

	public boolean isAlarmOn() {
		return alarmOn;
	}

	public void setAlarmOn(boolean alarmOn) {
		this.alarmOn = alarmOn;
	}

	public int getAlarmHour() {
		return alarmHour;
	}

	public void setAlarmHour(int alarmHour) {
		this.alarmHour = alarmHour;
	}

	public int getAlarmMinute() {
		return alarmMinute;
	}

	public void setAlarmMinute(int alarmMinute) {
		this.alarmMinute = alarmMinute;
	}

	public boolean isAlarmAM() {
		return alarmAM;
	}

	public void setAlarmAM(boolean alarmAM) {
		this.alarmAM = alarmAM;
	}

	public void setNationReligionStrength(EReligionStrength nationReligionStrength) {
		this.nationReligionStrength = nationReligionStrength;
	}

	public EReligionStrength getNationReligionStrength() {
		return nationReligionStrength;
	}

	public void setNationFlag(Flag nationFlag) {
		this.nationFlag = nationFlag;
	}

	public Flag getNationFlag() {
		return nationFlag;
	}

	public void setClades(ArrayList<Clade> clades) {
		this.clades = clades;
	}
	
	public void addClade(Clade clade) {
		this.clades.add(clade);
	}

	public ArrayList<Clade> getClades() {
		return clades;
	}

	public void setReligions(ArrayList<Religion> religions) {
		this.religions = religions;
	}
	
	public void addReligion(Religion religion) {
		religions.add(religion);
	}

	public ArrayList<Religion> getReligions() {
		return religions;
	}

	public void setStateReligion(StateReligion stateReligion) {
		this.stateReligion = stateReligion;
	}

	public StateReligion getStateReligion() {
		return stateReligion;
	}

	public void setCoreClade(Clade coreClade) {
		this.coreClade = coreClade;
	}

	public Clade getCoreClade() {
		return coreClade;
	}
	
	public HashMap<String, CustomGalaxyData> getAllCustomGalaxyData() {
		return this.customData;
	}
	
	public void setAllCustomGalaxyData(HashMap<String, CustomGalaxyData> galData) {
		this.customData.clear();
		this.customData.putAll(galData);
	}
	
	public CustomGalaxyData getCustomGalaxyData(String galRef) {
		return this.customData.get(galRef);
	}

}
